# -*- coding: utf-8 -*-
''' Address type (AT) tests
'''
import scopt.test.common
from scopt.mpu.business.settings.handlers import address_type


class AddressTypeCreate(scopt.test.common.ScoptTest):
    ''' AT creation tests
    MPU should:

    1. test_at_create_unique
        allow to create AT
    2. test_at_create_duplicate
        disallow to create AT with same name
    3. test_at_create_read
        create AT and retrieve it with returned AT entry id
    '''
    def test_at_create_unique(self):
        # SomeNewType is not part of demo data
        request = self.request(address_type.create)
        request['reqd'] = {'name': 'SomeNewType'}

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

    def test_at_create_duplicate(self):
        # Home/Domov is part of demo data
        request = self.request(address_type.create)
        request['reqd'] = {'name': 'Home/Domov'}

        response = self.send_request(request,
                                     pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.violation.unique_key')

    def test_at_create_read(self):
        # SomeNewType is not part of demo data
        at_to_create = 'SomeNewType'
        create_request = self.request(address_type.create)
        create_request['reqd'] = {'name': at_to_create}

        create_response = self.send_request(create_request)

        select_request = self.request(address_type.select)
        select_request['reqd'] = {'id': create_response['resd']['id']}
        select_response = self.send_request(select_request)
        select_resd = select_response['resd']
        at_name_updated = select_resd[0]['name']

        self.assertStatus(select_response, 'OK')
        self.assertEqual(len(select_resd), 1)
        self.assertEqual(at_name_updated, at_to_create)


class AddressTypeSelect(scopt.test.common.ScoptTest):
    ''' AT select tests
    MPU should:

    1. test_address_type_select_one ->
        select one AT by at_id
    2. test_address_type_select_all ->
        select all ATs by not providing id
    3. test_address_type_select_none ->
        select none AT by providing id of non existent record
    '''
    def test_address_type_select_one(self):
        # row with id 1 is part of demo data
        request = self.request(address_type.select)
        request['reqd'] = {'id': 1}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 1)

    def test_address_type_select_all(self):
        # there are 3 rows in AT demo data
        request = self.request(address_type.select)
        request['reqd'] = {}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 3)

    def test_address_type_select_none(self):
        # row with id of 200 is not present in demo data
        request = self.request(address_type.select)
        request['reqd'] = {'id': 200}

        response = self.send_request(request)
        data = response['resd']

        self.assertStatus(response, 'OK')
        self.assertEqual(len(data), 0)


class AddressTypeUpdate(scopt.test.common.ScoptTest):
    ''' AT update tests
    MPU should:

    1. test_address_type_update_new_name ->
        allow update AT to other unique name
    2. test_address_type_update_duplicate_name ->
        disallow update AT to name which is not unique
    3. test_address_type_update_invalid_id ->
        disallow update AT with invalid id
    4. test_address_type_update_missing_id ->
        disallow update AT with id is missing
    5. test_at_update_read
        update and read AT by its ID
    '''
    def test_address_type_update_new_name(self):
        # row with id 1 is part of demo data
        request = self.request(address_type.update)
        request['reqd'] = {'id': 1,
                           'name': 'Warehouse/Sklad - Updated'}

        response = self.send_request(request)

        self.assertStatus(response, 'OK')

    def test_address_type_update_duplicate_name(self):
        # row with name 'Office/Kancelária' is part of demo data
        request = self.request(address_type.update)
        request['reqd'] = {'id': 1,
                           'name': u'Office/Kancelária'}

        response = self.send_request(request, pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.violation.unique_key')

    def test_address_type_update_invalid_id(self):
        # rows with id over 100 are not part of demo data
        request = self.request(address_type.update)
        request['reqd'] = {'id': 101,
                           'name': 'New Type'}

        response = self.send_request(request, pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_invalid')

    def test_address_type_update_missing_id(self):
        request = self.request(address_type.update)
        request['reqd'] = {'name': 'New Type'}

        response = self.send_request(request, pass_interrupts=True)

        self.assertStatus(response, 'INT', 'business.record_no.is_none')

    def test_at_update_read(self):
        # SomeNewType is not part of demo data
        at_id_to_update = 1
        at_name_to_update = 'SomeNewType'
        update_request = self.request(address_type.update)
        update_request['reqd'] = {'id': at_id_to_update,
                                  'name': at_name_to_update}

        self.send_request(update_request)

        select_request = self.request(address_type.select)
        select_request['reqd'] = {'id': at_id_to_update}
        select_response = self.send_request(select_request)
        select_resd = select_response['resd']
        at_name_updated = select_resd[0]['name']

        self.assertStatus(select_response, 'OK')
        self.assertEqual(len(select_resd), 1)
        self.assertEqual(at_name_updated, at_name_to_update)
